﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace JAAF.UI.WPF
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:JAAF.UI.WPF.Controls"
    ///
    ///
    /// Step 1b) Using this custom control in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:JAAF.UI.WPF.Controls;assembly=JAAF.UI.WPF.Controls"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Browse to and select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your control in the XAML file.
    ///
    ///     <MyNamespace:RoundedBox2/>
    ///
    /// </summary>
    public class ClippingBorder : Border 
    {        
        protected override void OnRender(DrawingContext dc) 
        {            
            OnApplyChildClip();                        
            base.OnRender(dc);        
        }        
        
        public override UIElement Child         
        {            
            get            
            {                
                return base.Child;            
            }            
            
            set            
            {                
                if (this.Child != value)                
                {
                    if(this.Child != null)                    
                    {                        
                        // Restore original clipping                        
                        this.Child.SetValue(UIElement.ClipProperty, _oldClip);                    
                    }                    
                    
                    if(value != null)                    
                    {                        
                        _oldClip = value.ReadLocalValue(UIElement.ClipProperty);                    
                    }                    
                    else                     
                    {                        
                        // If we dont set it to null we could leak a Geometry object                        
                        _oldClip = null;                    
                    }                    
                    
                    base.Child = value;                
                }            
            }        
        }        
        
        protected virtual void OnApplyChildClip()        
        {            
            UIElement child = this.Child;            
            if(child != null)            
            {                
                _clipRect.RadiusX = _clipRect.RadiusY = Math.Max(0.0, this.CornerRadius.TopLeft - (this.BorderThickness.Left * 0.5));                
                _clipRect.Rect = new Rect(Child.RenderSize);                
                child.Clip = _clipRect;            
            }        
        }        
        
        private RectangleGeometry _clipRect = new RectangleGeometry();        
        private object _oldClip;    
    }
}
